package tc.de.krawallmann.achievement;

import java.io.Serializable;

import tc.de.krawallmann.gravoblocks.resource.Language;
import tc.de.krawallmann.util.MD5;

/**
 * The class Score represents a basic achievement.
 * 
 * @author KrawallMann
 * @version 1.0
 */
public class Achievement implements Serializable {

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 3171225735345676605L;

	/** The md5 checksum. */
	private String checksum;

	/** The game. */
	private String game;

	/** Do you receive this achevement ingame? */
	private boolean ingame;

	/** The internal name string. */
	private String internalString;

	/** The points. */
	private int points;

	/**
	 * Instantiates a new achievement.
	 * 
	 * @deprecated For deserialization only!
	 */
	@Deprecated
	public Achievement() {
		super();
	}

	/**
	 * Instantiates a new achievement.
	 * 
	 * @param game
	 *            the game
	 * @param ingame
	 *            the ingame
	 * @param internalString
	 *            the internal name string
	 * @param points
	 *            the points
	 */
	public Achievement(final String game, final boolean ingame, final String internalString,
			final int points) {
		super();
		this.ingame = ingame;
		this.game = game;
		this.points = points;
		this.internalString = internalString;
		checksum = calculateChecksum();
	}

	/**
	 * Gets the checksum.
	 * 
	 * @return the checksum
	 */
	public String getChecksum() {
		return checksum;
	}

	/**
	 * Gets the game.
	 * 
	 * @return the game
	 */
	public String getGame() {
		return game;
	}

	/**
	 * Gets the internal name string.
	 * 
	 * @return the internal string
	 */
	public String getInternalString() {
		return internalString;
	}

	/**
	 * Gets the name.
	 * 
	 * @return the name
	 */
	public String getName() {
		return Language.getString("Achievement." + internalString);
	}

	/**
	 * Gets the points.
	 * 
	 * @return the points
	 */
	public int getPoints() {
		return points;
	}

	/**
	 * Checks if this achievement is cheated.
	 * 
	 * @return true, if is cheat
	 */
	public boolean isCheat() {
		return !checksum.equals(calculateChecksum()) || "FAILURE".equals(checksum);
	}

	/**
	 * Do you receive this achievement ingame?
	 * 
	 * @return true, if you receive this achievement ingame
	 */
	public boolean isIngame() {
		return ingame;
	}

	/**
	 * Sets the checksum.
	 * 
	 * @param hash
	 *            the new checksum
	 */
	@Deprecated
	public void setChecksum(final String hash) {
		checksum = hash;
	}

	/**
	 * Sets the game.
	 * 
	 * @param game
	 *            the new game
	 */
	@Deprecated
	public void setGame(final String game) {
		this.game = game;
	}

	/**
	 * Sets the ingame status.
	 * 
	 * @param ingame
	 *            the new ingame status
	 */
	@Deprecated
	public void setIngame(final boolean ingame) {
		this.ingame = ingame;
	}

	/**
	 * Sets the internal name string.
	 * 
	 * @param internalString
	 *            the new internal name string
	 */
	@Deprecated
	public void setInternalString(final String internalString) {
		this.internalString = internalString;
	}

	/**
	 * Sets the points.
	 * 
	 * @param score
	 *            the new points
	 */
	@Deprecated
	public void setPoints(final int score) {
		points = score;
	}

	/**
	 * Calculate checksum.
	 * 
	 * @return the string
	 */
	private String calculateChecksum() {
		final String nameScoreMD5 = MD5.md5(Integer.toString(points));
		final String allMD5 =
				MD5.md5(nameScoreMD5 + MD5.md5(Integer.toHexString(points)) + MD5.md5(game));
		return MD5.md5(allMD5 + nameScoreMD5);
	}
}
